package com.lx.boot.web.convert.serializer;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.lx.boot.web.convert.DFunction;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.util.Objects;

@Slf4j
public class SerializerHandler extends JsonSerializer<Object> implements ContextualSerializer {

    private Class filedType;

    private Annotation annotation;

    private DFunction<SerializerPara, Annotation, ? extends Object> function;

    @Override
    public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        gen.writeObject(function.apply(new SerializerPara(gen, value,filedType),annotation));
    }

    
    @SneakyThrows
    @Override
    public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {
        if (filedType != null){
            return this;
        }
        filedType = property.getType().getRawClass();
        Serializer serializer = property.getAnnotation(Serializer.class);
        if (Objects.nonNull(serializer)) {
            this.annotation = property.getAnnotation(serializer.value());
            if (this.annotation == null){
                this.annotation = serializer;
            }
            this.function = (DFunction<SerializerPara, Annotation, ? extends Object>) serializer.function().getConstructor().newInstance();
            return this;
        }
        return prov.findValueSerializer(property.getType(), property);
    }
}
